------------------------------------------------------------------------------------------------------------------------------------------------
-- -- tasks base lib
local function language_change_say(theNPC)
    theNPC.CHAT_TABLE = {}
    pcall(function()
        -- theNPC.npc_base_lib:Get_Language() == "ch"
        theNPC.CHAT_TABLE = TUNING.NPC_CHAT_TABLE[ theNPC.npc_base_lib:Get_Language() ] ["npc_event_maxwell_and_shadow"] or {}
    end)
end
local function GetStringsTable()
    return TUNING.NPC_CHAT_TABLE[ type(TUNING.__NPC_LANGUAGE)=="function" and TUNING.__NPC_LANGUAGE() or TUNING.__NPC_LANGUAGE ] ["npc_event_maxwell_and_shadow"] or {}
end

-------------------------------------------------------------------------------------------------------------------------------------------------
local function PLAYER_TASK_INIT(inst)
    local player = inst.entity:GetParent()
    player.AnimState:SetMultColour(0, 0, 0, .4)
    player.____npc_event_maxwell_and_shadow_attaked_fn = function(player,cmd_table)
        if cmd_table == nil then
            return
        end
        if cmd_table.attacker == nil then
            return
        end

        if cmd_table.attacker:HasTag("shadow") then
            --------------------------------------------------------------------------------------------------
            if player.____npc_event_maxwell_and_shadow_attaked_fn then
                player:RemoveEventCallback("attacked",player.____npc_event_maxwell_and_shadow_attaked_fn)
                player.____npc_event_maxwell_and_shadow_attaked_fn = nil
            end
            if player.____npc_event_maxwell_and_death_fn then
                player:RemoveEventCallback("death",player.____npc_event_maxwell_and_death_fn)
                player.____npc_event_maxwell_and_death_fn = nil
            end
            --------------------------------------------------------------------------------------------------

            player.npc_base_lib:Throw_Out_Items({
                target = player,
                name = "nightmarefuel",
                num = 30,
                range = 6,
                height = 8,
                random_height = true
            })
            -- player:RemoveDebuff("npc_event_maxwell_and_shadow")  --- 这条发神经用不了
            local debuff_inst = player:GetDebuff("npc_event_maxwell_and_shadow")
            if debuff_inst then
                debuff_inst:Remove()
            end
            player.AnimState:SetMultColour(255, 255, 255, 1)

            player.npc_base_lib:Player_Killed_With_Announce(player:GetDisplayName()..GetStringsTable().kill_announce,"npc_event_maxwell_and_shadow")
            
            -----------------
        end

    end

    

    player:ListenForEvent("attacked",player.____npc_event_maxwell_and_shadow_attaked_fn)

    ------------------------------------------------------------------------------------------------------------
    --- 如果玩家死了，移除debuff
    player.____npc_event_maxwell_and_death_fn = function(player)
        --------------------------------------------------------------------------------------------------
        if player.____npc_event_maxwell_and_shadow_attaked_fn then
            player:RemoveEventCallback("attacked",player.____npc_event_maxwell_and_shadow_attaked_fn)
            player.____npc_event_maxwell_and_shadow_attaked_fn = nil
        end
        if player.____npc_event_maxwell_and_death_fn then
            player:RemoveEventCallback("death",player.____npc_event_maxwell_and_death_fn)
            player.____npc_event_maxwell_and_death_fn = nil
        end
        --------------------------------------------------------------------------------------------------
        local debuff_inst = player:GetDebuff("npc_event_maxwell_and_shadow")
        if debuff_inst then
            debuff_inst:Remove()
        end
        player.AnimState:SetMultColour(255, 255, 255, 1)
        player.npc_base_lib:Throw_Out_Items({
            target = player,
            name = "nightmarefuel",
            num = 30,
            range = 6,
            height = 8,
            random_height = true
        })

    end
    player:ListenForEvent("death",player.____npc_event_maxwell_and_death_fn)
    ------------------------------------------------------------------------------------------------------------
end

local function PLAYER_TASK(inst)
    local player = inst.entity:GetParent()

    if player.npc_everything_data:Add("npc_event_maxwell_and_shadow_time",1) % 5 == 0 then
        player.AnimState:SetMultColour(0, 0, 0, .4)
        player.npc_everything_data:Set("npc_event_maxwell_and_shadow_time",0)
        local pt = Vector3(player.Transform:GetWorldPosition())
        SpawnPrefab("npc_fx_shadow_feather"):PushEvent("Set",{ pt = pt })
    end

end

--------------------------------------------------------------------------------------------------------------------------------------------------

local function Time_Out_Leave(inst)
    local theNPC = inst.entity:GetParent()
    local time = theNPC.npc_base_lib:Get_Time_Out()
    if time then
        inst:DoTaskInTime(time,function()
            inst:Remove()
            theNPC:AddDebuff("npc_event_leave","npc_event_leave")
            theNPC.npc_base_lib:Say(theNPC.CHAT_TABLE.time_out)
            print("Warning : npc time out and leave")
        end)
    end
end

local function debuff_add_2_player(theNPC,theplayer)
    -------------------------------------------------------------
    --- -- 如果给玩家加debuff 前 玩家是 死掉的，直接掉落材料
    if theplayer:HasTag("playerghost") then
        -- local pt = Vector3( theplayer.Transform:GetWorldPosition())
        theNPC.npc_base_lib:Throw_Out_Items({
            target = theplayer,
            name = "nightmarefuel",
            num = 40,
            range = 6,
            height = 8,
            random_height = true
        })
        return
    end
    -------------------------------------------------------------
    ---- 如果玩家身上已经有debuff，则直接杀死玩家
    if theplayer:HasDebuff("npc_event_maxwell_and_shadow") then
        theNPC.npc_base_lib:Throw_Out_Items({
            target = theplayer,
            name = "nightmarefuel",
            num = 30,
            range = 6,
            height = 8,
            random_height = true
        })

        theplayer:GetDebuff("npc_event_maxwell_and_shadow"):Remove()
        theplayer.AnimState:SetMultColour(255, 255, 255, 1)


        theplayer.npc_base_lib:Player_Killed_With_Announce(theplayer:GetDisplayName()..GetStringsTable().kill_announce,"npc_event_maxwell_and_shadow")

        

        if theplayer.____npc_event_maxwell_and_shadow_attaked_fn then
            theplayer:RemoveEventCallback("attacked",theplayer.____npc_event_maxwell_and_shadow_attaked_fn)
            theplayer.____npc_event_maxwell_and_shadow_attaked_fn = nil
        end
        return
    end
    -------------------------------------------------------------
    theplayer:AddDebuff("npc_event_maxwell_and_shadow","npc_event_maxwell_and_shadow")
    -------------------------------------------------------------
end

local function NPC_TASKS_INIT(inst)
    local theNPC = inst.entity:GetParent()
    language_change_say(theNPC)
    Time_Out_Leave(inst)
    
    theNPC.npc_base_lib:Equip_Random_Hat()
    theNPC.npc_base_lib:Equip_Random_Cloth()
    -- theNPC.npc_base_lib:Equip_Random_Weapon()
    theNPC:AddTag("INLIMBO")
    theNPC:AddTag("notarget")
    theNPC:AddTag("noattack")
    theNPC:AddTag("invisible")
    -- theNPC:AddTag("Unable_To_Refuse")
    theNPC.npc_event = inst.prefab

    local whip = SpawnPrefab("whip")
    theNPC.npc_base_lib:Change_Item_Skin(whip)
    theNPC.npc_base_lib:Equip(whip)
end

local function NPC_TASKS(inst)
    local theNPC = inst.entity:GetParent()
    if TheWorld.state.isnight  or TheWorld:HasTag("cave") then
        theNPC.npc_base_lib:Try_2_Set_Light(true)
    else
        theNPC.npc_base_lib:Try_2_Set_Light(false)
    end
    local theplayer = theNPC.__link_player
    if theplayer == nil or theplayer:IsValid() == false then
        -- theNPC:RemoveDebuff(inst.prefab)
        inst:Remove()
        theNPC:AddDebuff("npc_event_leave","npc_event_leave")
        print("Warning : theNPC.__link_player == nil")
        return
    end

    if theNPC.event_step == nil then

        if theNPC.npc_base_lib:Close_2_Target_In_Range({range = 4}) == true then
            theNPC.npc_base_lib:FaceToInst(theplayer)
            theNPC.npc_base_lib:Action_WhipAttack()
            theNPC.event_step = 1
        end        
    elseif theNPC.event_step == 1 then
        debuff_add_2_player(theNPC,theplayer)            
        theNPC.event_step = 2
    elseif theNPC.event_step == 2 then
        -- theNPC.event_step = theNPC.event_step + 1
        -- theNPC:RemoveDebuff(inst.prefab)
        inst:Remove()
        theNPC.npc_base_lib:Say(theNPC.CHAT_TABLE.hahaha)
        theNPC:AddDebuff("npc_event_leave","npc_event_leave")
    end
end
--------------------------------------------------------------------------------------------------------------------------------------------------

local function OnAttached(inst,target) -- when the debuff on or player is newSpawn(or through the cave)
    inst.entity:SetParent(target.entity)
    inst.Network:SetClassifiedTarget(target)
    local PLAYER_OR_NPC = inst.entity:GetParent()

    local flag ,error_code= pcall(function(inst,target)
        if TheWorld.ismastersim then

            if PLAYER_OR_NPC:HasTag("player") then
                PLAYER_TASK_INIT(inst)
            else
                NPC_TASKS_INIT(inst)
            end


        end
    end,inst,target)
    if flag == false  then
        print("Error : OnAttached(inst,target) ",inst.prefab)
        print(error_code)
        if  not PLAYER_OR_NPC:HasTag("player") then
            PLAYER_OR_NPC:Remove()
        end
    end
end

local function OnDetached(inst) -- When eliminating from the outside
    local player = inst.entity:GetParent()   
    -- print(" FROM OUSIDE REMOVE ")
    
    -- inst:Remove()
end

local function ExtendDebuff(inst)
    -- inst.countdown = 3 + (inst._level:value() < CONTROL_LEVEL and EXTEND_TICKS or math.floor(TUNING.STALKER_MINDCONTROL_DURATION / FRAMES + .5))
end



local function OnUpdate(inst,ismastersim)
    local PLAYER_OR_NPC = inst.entity:GetParent()

    local flag,error_code = pcall(function(inst,ismastersim)
        -- local NPC = inst.entity:GetParent()
        if TheWorld.ismastersim then
            if PLAYER_OR_NPC:HasTag("player") then
                PLAYER_TASK(inst)
            else
                NPC_TASKS(inst)
            end

        end
    end,inst,ismastersim)
    if flag == false then
        print("Error : OnUpdate(inst,ismastersim) ,step:",PLAYER_OR_NPC.event_step ,inst.prefab)
        print(error_code)
        PLAYER_OR_NPC:Remove()
    end
end

local function fn()
    local inst = CreateEntity()

    inst.entity:AddTransform()
    inst.entity:AddNetwork()

    inst:AddTag("CLASSIFIED")


    -- inst:DoPeriodicTask(1, OnUpdate, nil, TheWorld.ismastersim)  -- in one seconds
    inst:DoPeriodicTask( 0.5, OnUpdate, nil, TheWorld.ismastersim)  -- in 0.5 seconds

    inst.entity:SetPristine()

    if not TheWorld.ismastersim then
        return inst
    end

    inst:AddComponent("debuff")
    inst.components.debuff:SetAttachedFn(OnAttached)
    inst.components.debuff.keepondespawn = true -- 是否保持debuff 到下次登陆
    -- inst.components.debuff:SetDetachedFn(inst.Remove)
    inst.components.debuff:SetDetachedFn(OnDetached)
    -- inst.components.debuff:SetExtendedFn(ExtendDebuff)
    -- ExtendDebuff(inst)


    return inst
end

return Prefab("npc_event_maxwell_and_shadow", fn)
-- ThePlayer:RemoveDebuff("npc_event_maxwell_and_shadow")